home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / comm / term / term34Source.lha / termPacket.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  24KB  |  1,067 lines

  1. /*
  2. **    termPacket.c
  3. **
  4. **    Support routines for the `packet window'
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* A custom message structure. */
  13.  
  14. struct PacketMessage
  15. {
  16.     struct Message     VanillaMessage;
  17.     LONG         Line;
  18. };
  19.  
  20.     /* Some private data required to handle both the window,
  21.      * the editing functions and the command history buffer.
  22.      */
  23.  
  24. STATIC struct Hook         PacketHook;
  25. STATIC UBYTE             PacketWorkBuffer[256];
  26. STATIC struct StringInfo    *PacketInfo;
  27.  
  28. STATIC struct MsgPort        *PacketPort;
  29.  
  30. STATIC LONG             PacketLine;
  31. STATIC LONG             PacketCount;
  32. STATIC STRPTR             PacketString    = NULL;
  33. STATIC LONG             PacketX    = -1,
  34.                  PacketY    = -1,
  35.                  PacketWidth    = -1,
  36.                  PacketHeight    = -1;
  37.  
  38. STATIC BYTE             HasList    = FALSE;
  39.  
  40.     /* Gadget IDs */
  41.  
  42. enum    {    GAD_STRING, GAD_LIST };
  43.  
  44.     /* The menu to attach to the packet window. */
  45.  
  46. enum    {    MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,MEN_QUITPANEL };
  47.  
  48. STATIC struct NewMenu NewPacketMenu[] =
  49. {
  50.     { NM_TITLE, NULL,         0 , 0, 0, (APTR)0},
  51.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_LOADHISTORY},
  52.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_SAVEHISTORY},
  53.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  54.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_CLEARHISTORY},
  55.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  56.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_OTHERWINDOW},
  57.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  58.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_QUITPANEL},
  59.     { NM_END, 0,             0 , 0, 0, (APTR)0}
  60. };
  61.  
  62.     /* SendPacketMsg(LONG Line):
  63.      *
  64.      *    Tell the main process to display a certain line.
  65.      */
  66.  
  67. STATIC VOID __regargs
  68. SendPacketMsg(LONG Line)
  69. {
  70.     struct PacketMessage *Msg;
  71.  
  72.     if(Msg = (struct PacketMessage *)AllocVec(sizeof(struct PacketMessage),MEMF_PUBLIC | MEMF_CLEAR))
  73.     {
  74.         Msg -> VanillaMessage . mn_Length    = sizeof(struct PacketMessage);
  75.         Msg -> Line                = Line;
  76.  
  77.         PutMsg(PacketPort,Msg);
  78.     }
  79. }
  80.  
  81.     /* ClearPacketHistory():
  82.      *
  83.      *    Release the command history.
  84.      */
  85.  
  86. VOID
  87. ClearPacketHistory()
  88. {
  89.     if(HasList)
  90.     {
  91.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  92.             GTLV_Labels,~0,
  93.         TAG_DONE);
  94.     }
  95.  
  96.     FreeList(&PacketHistoryList);
  97.  
  98.     PacketCount = PacketLine = 0;
  99.  
  100.     if(HasList)
  101.     {
  102.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  103.             GTLV_Labels,&PacketHistoryList,
  104.         TAG_DONE);
  105.     }
  106.  
  107.     PacketString = NULL;
  108. }
  109.  
  110.     /* DeletePacketWindow():
  111.      *
  112.      *    Delete the packet window and release the command
  113.      *    history.
  114.      */
  115.  
  116. VOID
  117. DeletePacketWindow(BYTE WindowOnly)
  118. {
  119.     CheckItem(MEN_PACKET_WINDOW,FALSE);
  120.  
  121.     if(PacketWindow)
  122.     {
  123.         PacketWindow -> Flags |= WFLG_RMBTRAP;
  124.  
  125.         ClearMenuStrip(PacketWindow);
  126.  
  127.         if(PacketGadgetList)
  128.             RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  129.  
  130.         PacketX        = PacketWindow -> LeftEdge;
  131.         PacketY        = PacketWindow -> TopEdge;
  132.  
  133.         PacketWidth    = PacketWindow -> Width;
  134.         PacketHeight    = PacketWindow -> Height;
  135.  
  136.         CloseWindow(PacketWindow);
  137.  
  138.         PacketWindow = NULL;
  139.     }
  140.  
  141.     if(PacketGadgetList)
  142.     {
  143.         FreeGadgets(PacketGadgetList);
  144.  
  145.         PacketGadgetList = NULL;
  146.     }
  147.  
  148.     if(PacketMenu)
  149.     {
  150.         FreeMenus(PacketMenu);
  151.  
  152.         PacketMenu = NULL;
  153.     }
  154.  
  155.     if(PacketPort)
  156.     {
  157.         struct Message *Message;
  158.  
  159.         while(Message = GetMsg(PacketPort))
  160.             FreeVec(Message);
  161.  
  162.         FreeVec(PacketPort);
  163.  
  164.         PacketPort = NULL;
  165.     }
  166.  
  167.     if(!WindowOnly)
  168.     {
  169.         HasList = FALSE;
  170.  
  171.         ClearPacketHistory();
  172.     }
  173. }
  174.  
  175.     /* AddPacketHistory(STRPTR Buffer):
  176.      *
  177.      *    Add a line to the packet window command history. This
  178.      *    works very much the same as the AddLine()-routine.
  179.      */
  180.  
  181. VOID
  182. AddPacketHistory(STRPTR Buffer)
  183. {
  184.     struct Node *SomeNode;
  185.  
  186.     if(HasList)
  187.     {
  188.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  189.             GTLV_Labels,~0,
  190.         TAG_DONE);
  191.     }
  192.  
  193.     if(SomeNode = CreateNode(Buffer))
  194.     {
  195.         AddTail(&PacketHistoryList,SomeNode);
  196.  
  197.         PacketCount = ++PacketLine;
  198.     }
  199.  
  200.     if(HasList)
  201.     {
  202.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  203.             GTLV_Top,    PacketCount - 1,
  204.             GTLV_Labels,    &PacketHistoryList,
  205.         TAG_DONE);
  206.     }
  207. }
  208.  
  209.     /* CreateAllGadgets():
  210.      *
  211.      *    Create the packet string gadget.
  212.      */
  213.  
  214. STATIC struct Gadget *
  215. CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo)
  216. {
  217.     struct Gadget        *Gadget;
  218.     struct NewGadget     NewGadget;
  219.  
  220.     SZ_SizeSetup(Window -> WScreen,&UserFont,TRUE);
  221.  
  222.     memset(&NewGadget,0,sizeof(struct NewGadget));
  223.  
  224.     if(Gadget = CreateContext(GadgetList))
  225.     {
  226.         WORD Rest,StringHeight,ProtoHeight;
  227.  
  228.         StringHeight    = SZ_Height(STRING_KIND,0,0);
  229.         ProtoHeight    = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 2 + StringHeight + 2;
  230.         Rest        = (PacketHeight - 2 - ProtoHeight - 2) / UserFontHeight;
  231.  
  232.         NewGadget . ng_Width        = Width - 26;
  233.         NewGadget . ng_Height        = StringHeight;
  234.         NewGadget . ng_GadgetText    = NULL;
  235.         NewGadget . ng_TextAttr        = &UserFont;
  236.         NewGadget . ng_VisualInfo    = VisualInfo;
  237.         NewGadget . ng_GadgetID        = GAD_STRING;
  238.         NewGadget . ng_Flags        = 0;
  239.         NewGadget . ng_LeftEdge        = 6;
  240.         NewGadget . ng_TopEdge        = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 2;
  241.  
  242.         GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  243.             GTST_MaxChars,    256,
  244.             GTST_EditHook,    &PacketHook,
  245.             GA_TabCycle,    FALSE,
  246.         TAG_DONE);
  247.  
  248.             /* If the window is large enough to display the
  249.              * list, create the list view gadget.
  250.              */
  251.  
  252.         if(Rest > 0)
  253.         {
  254.             NewGadget . ng_Height        = 2 + Rest * UserFontHeight + 2 + StringHeight;
  255.             NewGadget . ng_GadgetID        = GAD_LIST;
  256.  
  257.             GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  258.                 GTLV_ShowSelected,    GadgetArray[GAD_STRING],
  259.                 GTLV_Labels,        &PacketHistoryList,
  260.                 GTLV_Selected,        PacketCount,
  261.                 GTLV_Top,        PacketCount,
  262.             TAG_DONE);
  263.  
  264.             if(Gadget)
  265.                 HasList = TRUE;
  266.             else
  267.                 HasList = FALSE;
  268.         }
  269.         else
  270.             HasList = FALSE;
  271.     }
  272.  
  273.     return(Gadget);
  274. }
  275.  
  276.     /* CreatePacketWindow():
  277.      *
  278.      *    Open the packet window and allocate the command history
  279.      *    buffer.
  280.      */
  281.  
  282. BYTE
  283. CreatePacketWindow()
  284. {
  285.     LocalizeMenu(NewPacketMenu,MSG_PACKET_PROJECT_MEN);
  286.  
  287.     if(PacketPort = (struct MsgPort *)AllocVec(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
  288.     {
  289.         if(PacketMenu = CreateMenus(NewPacketMenu,TAG_DONE))
  290.         {
  291.             if(LayoutMenus(PacketMenu,VisualInfo,
  292.                 GTMN_TextAttr,        &UserFont,
  293.                 GTMN_NewLookMenus,    TRUE,
  294.             TAG_DONE))
  295.             {
  296.                 LONG ProtoHeight;
  297.  
  298.                 SZ_SizeSetup(Window -> WScreen,&UserFont,TRUE);
  299.  
  300.                 ProtoHeight = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 2 + SZ_Height(STRING_KIND,0,0) + 2;
  301.  
  302.                 if(PacketWidth == -1)
  303.                     PacketWidth = Window -> Width;
  304.  
  305.                 if(PacketHeight < ProtoHeight)
  306.                     PacketHeight = ProtoHeight;
  307.  
  308.                 if(PacketX == -1 || (PacketX + PacketWidth > Window -> WScreen -> Width))
  309.                 {
  310.                     PacketX = Window -> LeftEdge;
  311.  
  312.                     if(PacketX + PacketWidth > Window -> WScreen -> Width)
  313.                         PacketWidth = Window -> WScreen -> Width - PacketX;
  314.                 }
  315.  
  316.                 if(PacketY == -1 || (PacketY + PacketHeight > Window -> WScreen -> Height))
  317.                 {
  318.                     PacketY = Window -> TopEdge + Window -> Height;
  319.  
  320.                     if(PacketY + PacketHeight > Window -> WScreen -> Height)
  321.                         PacketHeight = ProtoHeight;
  322.                 }
  323.  
  324.                 if(CreateAllGadgets(PacketWidth,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  325.                 {
  326.                     if(PacketWindow = OpenWindowTags(NULL,
  327.                         WA_Width,        PacketWidth,
  328.                         WA_Height,        PacketHeight,
  329.  
  330.                         WA_Left,        PacketX,
  331.                         WA_Top,            PacketY,
  332.  
  333.                         WA_Activate,        TRUE,
  334.                         WA_DragBar,        TRUE,
  335.                         WA_DepthGadget,        TRUE,
  336.                         WA_CloseGadget,        TRUE,
  337.                         WA_RMBTrap,        TRUE,
  338.                         WA_SizeGadget,        TRUE,
  339.                         WA_MinWidth,        80,
  340.                         WA_MinHeight,        ProtoHeight,
  341.                         WA_MaxWidth,        Window -> WScreen -> Width,
  342.                         WA_MaxHeight,        Window -> WScreen -> Height,
  343.                         WA_CustomScreen,    Window -> WScreen,
  344.                         WA_NoCareRefresh,    TRUE,
  345.                         WA_NewLookMenus,    TRUE,
  346.  
  347.                         WA_IDCMP,        STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,
  348.  
  349.                         WA_Title,        LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
  350.                     TAG_DONE))
  351.                     {
  352.                         CheckItem(MEN_PACKET_WINDOW,TRUE);
  353.  
  354.                         PacketPort -> mp_Flags        = PA_SIGNAL;
  355.                         PacketPort -> mp_SigBit        = PacketWindow -> UserPort -> mp_SigBit;
  356.                         PacketPort -> mp_SigTask    = PacketWindow -> UserPort -> mp_SigTask;
  357.  
  358.                         NewList(&PacketPort -> mp_MsgList);
  359.  
  360.                         PacketHook . h_Entry        = (LONG (*)())PacketKey;
  361.                         PacketHook . h_SubEntry        = NULL;
  362.                         PacketHook . h_Data        = NULL;
  363.  
  364.                         PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  365.  
  366.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  367.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  368.                         GT_RefreshWindow(PacketWindow,NULL);
  369.  
  370.                         SetMenuStrip(PacketWindow,PacketMenu);
  371.  
  372.                         PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  373.  
  374.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  375.  
  376.                         return(TRUE);
  377.                     }
  378.                 }
  379.             }
  380.         }
  381.     }
  382.  
  383.     DeletePacketWindow(FALSE);
  384.  
  385.     return(FALSE);
  386. }
  387.  
  388.     /* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  389.      *
  390.      *    This is a string gadget editing call back routine
  391.      *    (a so-called `hook') which is to perform all the
  392.      *    line editing and command history actions supported
  393.      *    by the packet window.
  394.      */
  395.  
  396. ULONG __saveds __asm
  397. PacketKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
  398. {
  399.         /* Someone activated the string gadget and
  400.          * hit a key.
  401.          */
  402.  
  403.     if(*Msg == SGH_KEY)
  404.     {
  405.             /* Right-Amiga-key was pressed, release the
  406.              * string gadget so user may select a menu
  407.              * item.
  408.              */
  409.  
  410.         if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  411.         {
  412.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  413.                 return(~0);
  414.             else
  415.             {
  416.                 Work -> Actions |= (SGA_END|SGA_REUSE);
  417.                 Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  418.  
  419.                 CommandWindow = Work -> GadgetInfo -> gi_Window;
  420.                 CommandGadget = Work -> Gadget;
  421.             }
  422.         }
  423.  
  424.         if(Work -> EditOp == EO_INSERTCHAR || Work -> EditOp == EO_REPLACECHAR)
  425.         {
  426.             if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  427.             {
  428.                 if(Work -> Code == 'c')
  429.                 {
  430.                     Work -> Actions &= ~SGA_USE;
  431.                     Work -> Actions |= SGA_BEEP;
  432.  
  433.                     if(Work -> PrevBuffer[0])
  434.                     {
  435.                         struct MsgPort *ReplyPort;
  436.  
  437.                         if(ReplyPort = CreateMsgPort())
  438.                         {
  439.                             struct Message ClipMessage;
  440.  
  441.                             ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  442.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  443.                             ClipMessage . mn_Length        = sizeof(struct Message);
  444.  
  445.                             PutMsg(ClipPort,&ClipMessage);
  446.  
  447.                             WaitPort(ReplyPort);
  448.  
  449.                             GetMsg(ReplyPort);
  450.  
  451.                             DeleteMsgPort(ReplyPort);
  452.  
  453.                             Work -> Actions &= ~SGA_BEEP;
  454.                         }
  455.                     }
  456.  
  457.                     return(~0);
  458.                 }
  459.  
  460.                 if(Work -> Code == 'v')
  461.                 {
  462.                     Work -> Actions &= ~SGA_USE;
  463.                     Work -> Actions |= SGA_BEEP;
  464.  
  465.                     if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  466.                     {
  467.                         struct MsgPort *ReplyPort;
  468.  
  469.                         if(ReplyPort = CreateMsgPort())
  470.                         {
  471.                             STATIC UBYTE    Buffer[2048];
  472.                             struct Message    ClipMessage;
  473.  
  474.                             Buffer[0] = 0;
  475.  
  476.                             ClipMessage . mn_Node . ln_Name    = Buffer;
  477.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  478.                             ClipMessage . mn_Length        = sizeof(struct Message);
  479.  
  480.                             PutMsg(ClipPort,&ClipMessage);
  481.  
  482.                             WaitPort(ReplyPort);
  483.  
  484.                             GetMsg(ReplyPort);
  485.  
  486.                             DeleteMsgPort(ReplyPort);
  487.  
  488.                             if(Buffer[0])
  489.                             {
  490.                                 WORD Len = strlen(Buffer);
  491.  
  492.                                 while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  493.                                     Len--;
  494.  
  495.                                 if(Len > 0)
  496.                                 {
  497.                                     STATIC UBYTE OtherBuffer[2048];
  498.  
  499.                                     Buffer[Len] = 0;
  500.  
  501.                                     if(Work -> StringInfo -> UndoBuffer)
  502.                                         strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  503.  
  504.                                     Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  505.  
  506.                                     if(Work -> BufferPos)
  507.                                         CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  508.  
  509.                                     OtherBuffer[Work -> BufferPos] = 0;
  510.  
  511.                                     strcat(OtherBuffer,Buffer);
  512.  
  513.                                     strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  514.  
  515.                                     strcpy(Work -> WorkBuffer,OtherBuffer);
  516.  
  517.                                     Work -> BufferPos += Len;
  518.                                     Work -> NumChars    += Len;
  519.  
  520.                                     Work -> Actions    |= SGA_USE;
  521.                                     Work -> EditOp     = EO_BIGCHANGE;
  522.  
  523.                                     Work -> Actions &= ~SGA_BEEP;
  524.                                 }
  525.                             }
  526.                             else
  527.                                 Work -> Actions &= ~SGA_BEEP;
  528.                         }
  529.                     }
  530.  
  531.                     return(~0);
  532.                 }
  533.             }
  534.         }
  535.  
  536.             /* The user pressed the cursor-right key to
  537.              * move the cursor to the next word in the buffer.
  538.              */
  539.  
  540.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  541.         {
  542.             if(Work -> BufferPos != Work -> NumChars)
  543.             {
  544.                 WORD i,Position = -1;
  545.  
  546.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  547.                 {
  548.                     if(Work -> WorkBuffer[i] == ' ')
  549.                     {
  550.                         for( ; i < Work -> NumChars ; i++)
  551.                         {
  552.                             if(Work -> WorkBuffer[i] != ' ')
  553.                             {
  554.                                 Position = i;
  555.                                 break;
  556.                             }
  557.                         }
  558.  
  559.                         break;
  560.                     }
  561.                 }
  562.  
  563.                 if(Position != -1)
  564.                     Work -> BufferPos = Position;
  565.                 else
  566.                     Work -> BufferPos = Work -> NumChars;
  567.  
  568.                 Work -> EditOp = EO_MOVECURSOR;
  569.             }
  570.         }
  571.  
  572.             /* The user pressed the cursor-right key to
  573.              * move the cursor to the previous word in the buffer.
  574.              */
  575.  
  576.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  577.         {
  578.             if(Work -> BufferPos)
  579.             {
  580.                 WORD i,Position = -1;
  581.  
  582.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  583.                 {
  584.                     if(Work -> WorkBuffer[i] != ' ')
  585.                     {
  586.                         Position = i;
  587.                         break;
  588.                     }
  589.                 }
  590.  
  591.                 if(Position == -1)
  592.                     Position = 0;
  593.  
  594.                 if(Position)
  595.                 {
  596.                     i = Position;
  597.  
  598.                     Position = -1;
  599.  
  600.                     for( ; i >= 0 ; i--)
  601.                     {
  602.                         if(Work -> WorkBuffer[i] == ' ')
  603.                         {
  604.                             Position = i + 1;
  605.                             break;
  606.                         }
  607.                     }
  608.                 }
  609.  
  610.                 if(Position != -1)
  611.                     Work -> BufferPos = Position;
  612.                 else
  613.                     Work -> BufferPos = 0;
  614.  
  615.                 Work -> EditOp = EO_MOVECURSOR;
  616.             }
  617.         }
  618.  
  619.             /* The user pressed the cursor-up key to
  620.              * scroll through the command history.
  621.              */
  622.  
  623.         if(Work -> IEvent -> ie_Code == CURSORUP)
  624.         {
  625.                 /* Shift key: jump to first command
  626.                  * history entry.
  627.                  */
  628.  
  629.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  630.             {
  631.                 if(PacketLine)
  632.                     SendPacketMsg(0);
  633.             }
  634.             else
  635.             {
  636.                 if(PacketLine && PacketCount > 0)
  637.                     SendPacketMsg(PacketCount - 1);
  638.             }
  639.         }
  640.  
  641.             /* The user pressed the cursor-down key to
  642.              * scroll through the command history.
  643.              */
  644.  
  645.         if(Work -> IEvent -> ie_Code == CURSORDOWN)
  646.         {
  647.                 /* Shift key: jump to last command
  648.                  * history entry.
  649.                  */
  650.  
  651.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  652.             {
  653.                 if(PacketLine > 0)
  654.                     SendPacketMsg(PacketLine);
  655.             }
  656.             else
  657.             {
  658.                 if(PacketCount < PacketLine)
  659.                     SendPacketMsg(PacketCount + 1);
  660.             }
  661.         }
  662.  
  663.         return(1);
  664.     }
  665.     else
  666.     {
  667.         if(*Msg == SGH_CLICK)
  668.             return(1);
  669.         else
  670.             return(0);
  671.     }
  672. }
  673.  
  674.     /* HandlePacket():
  675.      *
  676.      *    Process the input coming through the packet window.
  677.      */
  678.  
  679. BYTE
  680. HandlePacket()
  681. {
  682.     struct IntuiMessage    *Massage;
  683.     struct PacketMessage    *PacketMsg;
  684.     ULONG             IClass,Code;
  685.     struct Gadget        *Gadget;
  686.     struct FileRequester    *FileRequest;
  687.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  688.     BYTE             SwapWindow = FALSE;
  689.  
  690.         /* Are we already shut down? */
  691.  
  692.     if(PacketWindow)
  693.     {
  694.         BYTE Result = FALSE;
  695.  
  696.         if(Massage = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
  697.         {
  698.             IClass    = Massage -> Class;
  699.             Code    = Massage -> Code;
  700.             Gadget    = (struct Gadget *)Massage -> IAddress;
  701.  
  702.             GT_ReplyIMsg(Massage);
  703.  
  704.                 /* Re-enable the string gadget if necessary. */
  705.  
  706.             if(IClass == IDCMP_RAWKEY)
  707.             {
  708.                 if(Code == IECODE_UP_PREFIX|RAMIGA_CODE && CommandWindow == PacketWindow)
  709.                     ActivateGadget(CommandGadget,PacketWindow,NULL);
  710.  
  711.                 if(Code == HELP_CODE)
  712.                     GuideDisplay(CONTEXT_PACKETWINDOW);
  713.             }
  714.  
  715.                 /* Handle the menu. */
  716.  
  717.             if(IClass == IDCMP_MENUPICK)
  718.             {
  719.                 struct MenuItem *MenuItem;
  720.  
  721.                 while(Code != MENUNULL)
  722.                 {
  723.                     MenuItem = ItemAddress(PacketMenu,Code);
  724.  
  725.                     switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  726.                     {
  727.                         case MEN_QUITPANEL:
  728.  
  729.                             IClass = IDCMP_CLOSEWINDOW;
  730.                             break;
  731.  
  732.                         case MEN_LOADHISTORY:
  733.  
  734.                             BlockWindows();
  735.  
  736.                             if(FileRequest = GetFile(LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  737.                             {
  738.                                 if(GetFileSize(DummyBuffer))
  739.                                 {
  740.                                     BPTR SomeFile;
  741.  
  742.                                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  743.                                     {
  744.                                         if(PacketLine)
  745.                                         {
  746.                                             switch(MyEasyRequest(Window,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
  747.                                             {
  748.                                                 case 1:    ClearPacketHistory();
  749.                                                     break;
  750.  
  751.                                                 case 0:    Close(SomeFile);
  752.                                                     SomeFile = NULL;
  753.                                                     break;
  754.                                             }
  755.                                         }
  756.  
  757.                                         if(SomeFile)
  758.                                         {
  759.                                             WORD Len;
  760.  
  761.                                             LineRead(NULL,NULL,NULL);
  762.  
  763.                                             while(Len = LineRead(SomeFile,DummyBuffer,255))
  764.                                             {
  765.                                                 DummyBuffer[Len - 1] = 0;
  766.  
  767.                                                 AddPacketHistory(DummyBuffer);
  768.                                             }
  769.  
  770.                                             Close(SomeFile);
  771.                                         }
  772.                                     }
  773.                                 }
  774.  
  775.                                 FreeAslRequest(FileRequest);
  776.                             }
  777.  
  778.                             ReleaseWindows();
  779.                             break;
  780.  
  781.                         case MEN_SAVEHISTORY:
  782.  
  783.                             BlockWindows();
  784.  
  785.                             if(!PacketLine)
  786.                                 MyEasyRequest(Window,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  787.                             else
  788.                             {
  789.                                 if(FileRequest = GetFile(LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  790.                                 {
  791.                                     BPTR SomeFile = NULL;
  792.  
  793.                                         /* If the file we are about
  794.                                          * to create already exists,
  795.                                          * ask the user whether we are
  796.                                          * to create, append or skip
  797.                                          * the file.
  798.                                          */
  799.  
  800.                                     if(GetFileSize(DummyBuffer))
  801.                                     {
  802.                                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  803.                                         {
  804.                                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  805.                                                 break;
  806.  
  807.                                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  808.                                                 {
  809.                                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  810.                                                     {
  811.                                                         Close(SomeFile);
  812.  
  813.                                                         SomeFile = NULL;
  814.                                                     }
  815.                                                 }
  816.                                                 break;
  817.                                         }
  818.                                     }
  819.                                     else
  820.                                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  821.  
  822.                                     if(!SomeFile)
  823.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  824.                                     else
  825.                                     {
  826.                                         struct Node *SomeNode;
  827.  
  828.                                         SomeNode = PacketHistoryList . lh_Head;
  829.  
  830.                                         while(SomeNode -> ln_Succ)
  831.                                         {
  832.                                             FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name);
  833.  
  834.                                             SomeNode = SomeNode -> ln_Succ;
  835.                                         }
  836.  
  837.                                         Close(SomeFile);
  838.  
  839.                                         if(GetFileSize(DummyBuffer))
  840.                                         {
  841.                                             AddProtection(DummyBuffer,FIBF_EXECUTE);
  842.  
  843.                                             if(Config -> MiscConfig -> CreateIcons)
  844.                                                 AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  845.                                         }
  846.                                         else
  847.                                             DeleteFile(DummyBuffer);
  848.                                     }
  849.  
  850.                                     FreeAslRequest(FileRequest);
  851.                                 }
  852.                             }
  853.  
  854.                             ReleaseWindows();
  855.  
  856.                             break;
  857.  
  858.                         case MEN_CLEARHISTORY:
  859.  
  860.                             BlockWindows();
  861.  
  862.                             ClearPacketHistory();
  863.  
  864.                             ReleaseWindows();
  865.                             break;
  866.  
  867.                         case MEN_OTHERWINDOW:
  868.  
  869.                             SwapWindow = TRUE;
  870.                             break;
  871.                     }
  872.  
  873.                     Code = MenuItem -> NextSelect;
  874.                 }
  875.  
  876.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  877.             }
  878.  
  879.                 /* Shut down. */
  880.  
  881.             if(IClass == IDCMP_CLOSEWINDOW)
  882.             {
  883.                 DeletePacketWindow(FALSE);
  884.  
  885.                 return(FALSE);
  886.             }
  887.  
  888.                 /* Activate the string gadget as well. */
  889.  
  890.             if(IClass == IDCMP_ACTIVEWINDOW)
  891.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  892.  
  893.             if(IClass == IDCMP_NEWSIZE)
  894.             {
  895.                 PacketWindow -> Flags |= WFLG_RMBTRAP;
  896.  
  897.                 strcpy(DummyBuffer,PacketInfo -> Buffer);
  898.  
  899.                 RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  900.  
  901.                 FreeGadgets(PacketGadgetList);
  902.  
  903.                 PacketGadgetList = NULL;
  904.  
  905.                 SetAPen(PacketWindow -> RPort,0);
  906.                 RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
  907.                 RefreshWindowFrame(PacketWindow);
  908.  
  909.                 PacketHeight    = PacketWindow -> Height;
  910.                 PacketWidth    = PacketWindow -> Width;
  911.  
  912.                 if(CreateAllGadgets(PacketWindow -> Width,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  913.                 {
  914.                     PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  915.  
  916.                     strcpy(PacketInfo -> Buffer,DummyBuffer);
  917.  
  918.                     AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  919.                     RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  920.                     GT_RefreshWindow(PacketWindow,NULL);
  921.  
  922.                     PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  923.  
  924.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  925.                 }
  926.                 else
  927.                 {
  928.                     DeletePacketWindow(FALSE);
  929.  
  930.                     return(FALSE);
  931.                 }
  932.             }
  933.  
  934.             if(IClass == IDCMP_MOUSEBUTTONS)
  935.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  936.  
  937.                 /* User has entered a string. */
  938.  
  939.             if(IClass == IDCMP_GADGETUP)
  940.             {
  941.                 switch(Gadget -> GadgetID)
  942.                 {
  943.                     case GAD_STRING:
  944.  
  945.                             /* Is there anything in the buffer at all? */
  946.  
  947.                         if(PacketInfo -> Buffer[0])
  948.                         {
  949.                             strcpy(DummyBuffer,PacketInfo -> Buffer);
  950.  
  951.                             if(PacketString)
  952.                             {
  953.                                 if(strcmp(PacketString,DummyBuffer))
  954.                                     AddPacketHistory(DummyBuffer);
  955.  
  956.                                 PacketString = NULL;
  957.                             }
  958.                             else
  959.                                 AddPacketHistory(DummyBuffer);
  960.  
  961.                                 /* Convert alien IBM characters. */
  962.  
  963.                             if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  964.                             {
  965.                                 WORD i;
  966.                                 UBYTE Char;
  967.  
  968.                                 for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  969.                                 {
  970.                                     if(Char = IBMConversion[DummyBuffer[i]])
  971.                                         DummyBuffer[i] = Char;
  972.                                 }
  973.                             }
  974.  
  975.                                 /* Execute the command. */
  976.  
  977.                             SerialCommand(DummyBuffer);
  978.                         }
  979.  
  980.                             /* Clear the packet window string
  981.                              * gadget.
  982.                              */
  983.  
  984.                         GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  985.                             GTST_String,    "",
  986.                         TAG_DONE);
  987.  
  988.                             /* Send a terminating `CR'. */
  989.  
  990.                         switch(Config -> TerminalConfig -> SendCR)
  991.                         {
  992.                             case CR_ASCR:
  993.  
  994.                                 SerWrite("\r",1);
  995.                                 break;
  996.  
  997.                             case CR_ASCRLF:
  998.  
  999.                                 SerWrite("\r\n",2);
  1000.                                 break;
  1001.                         }
  1002.  
  1003.                             /* Re-activate the string gadget. */
  1004.  
  1005.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  1006.  
  1007.                         break;
  1008.  
  1009.                     case GAD_LIST:
  1010.  
  1011.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  1012.                         break;
  1013.                 }
  1014.             }
  1015.  
  1016.             if(SwapWindow)
  1017.                 BumpWindow(Window);
  1018.  
  1019.             Result = TRUE;
  1020.         }
  1021.  
  1022.         if(PacketMsg = (struct PacketMessage *)GetMsg(PacketPort))
  1023.         {
  1024.             struct Node *Node;
  1025.  
  1026.             Result = TRUE;
  1027.  
  1028.             if(Node = GetListNode(PacketMsg -> Line,&PacketHistoryList))
  1029.             {
  1030.                 PacketString = Node -> ln_Name;
  1031.  
  1032.                 if(HasList)
  1033.                 {
  1034.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1035.                         GTLV_Selected,    PacketMsg -> Line,
  1036.                         GTLV_Top,    PacketMsg -> Line,
  1037.                     TAG_DONE);
  1038.                 }
  1039.                 else
  1040.                 {
  1041.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1042.                         GTST_String,    Node -> ln_Name,
  1043.                     TAG_DONE);
  1044.                 }
  1045.             }
  1046.             else
  1047.             {
  1048.                 PacketString = NULL;
  1049.  
  1050.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1051.                     GTST_String,    "",
  1052.                 TAG_DONE);
  1053.             }
  1054.  
  1055.             PacketCount = PacketMsg -> Line;
  1056.  
  1057.             FreeVec(PacketMsg);
  1058.  
  1059.             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  1060.         }
  1061.  
  1062.         return(Result);
  1063.     }
  1064.  
  1065.     return(FALSE);
  1066. }
  1067.